package top.lixunda.ecommerce.server.good.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import top.lixunda.common.utils.ObjectValidators;
import top.lixunda.ecommerce.server.business.BaseServiceImpl;
import top.lixunda.ecommerce.server.good.api.entity.db.LogGoodPriceDO;
import top.lixunda.ecommerce.server.good.api.entity.db.SubGoodDO;
import top.lixunda.ecommerce.server.good.mapper.LogGoodPriceMapper;
import top.lixunda.ecommerce.server.good.service.ILogGoodPriceService;
import top.lixunda.ecommerce.server.good.service.ISubGoodService;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author Xumda
 * @since 2019-12-18
 */
@Service
public class LogGoodPriceServiceImpl
        extends BaseServiceImpl<LogGoodPriceMapper, LogGoodPriceDO>
        implements ILogGoodPriceService {

    private final ISubGoodService subGoodService;

    @Autowired
    public LogGoodPriceServiceImpl(ISubGoodService subGoodService) {
        this.subGoodService = subGoodService;
    }

    /**
     * 根据商品id查询商品的价格变化曲线
     *
     * @param id 商品id
     * @return 价格变化记录，默认时间升序排列
     */
    @Override
    public List<LogGoodPriceDO> queryByGoodId(Integer id) {
        if (ObjectValidators.isEmpty(id)) {
            throw getAppException("商品id不能为空");
        }
        return this.list(
                new LambdaQueryWrapper<LogGoodPriceDO>()
                        .eq(LogGoodPriceDO::getGoodId, id)
                        .orderByAsc(LogGoodPriceDO::getUpdateTime));
    }

    /**
     * 根据商品分类id查询商品某个分类的价格变化曲线
     *
     * @param id 商品分类id
     * @return 价格变化记录，默认时间升序排列
     */
    @Override
    public List<LogGoodPriceDO> queryByGoodTypeId(Integer id) {
        if (ObjectValidators.isEmpty(id)) {
            throw getAppException("商品分类id不能为空");
        }
        return this.list(
                new LambdaQueryWrapper<LogGoodPriceDO>()
                        .eq(LogGoodPriceDO::getSubGoodId, id)
                        .orderByAsc(LogGoodPriceDO::getUpdateTime)
        );
    }

    /**
     * 为某个子商品添加一条价格变化记录
     *
     * @param id    子商品id
     * @param price 新的价格，不能小于等于零
     * @return 返回添加的记录
     */
    @Override
    public LogGoodPriceDO addGoodPriceLog(Integer id, Double price) {
        if (ObjectValidators.isEmpty(id) || ObjectValidators.isEmpty(price)) {
            throw getAppException("商品类别id和价格不能为空");
        }
        if (price <= 0.0) {
            throw getAppException("价格不能小于等于零");
        }
        SubGoodDO subGoodDO = subGoodService.getById(String.valueOf(id));
        if (ObjectValidators.isEmpty(subGoodDO)) {
            throw getAppException("商品分类不存在");
        }
        LogGoodPriceDO logGoodPriceDO = new LogGoodPriceDO();
        logGoodPriceDO.setGoodId(subGoodDO.getGoodId());
        logGoodPriceDO.setGoodName(subGoodDO.getGoodName());
        logGoodPriceDO.setSubGoodId(subGoodDO.getId());
        logGoodPriceDO.setSubGoodName(subGoodDO.getSubGoodName());
        logGoodPriceDO.setPrice(BigDecimal.valueOf(price));
        logGoodPriceDO.setUpdateTime(LocalDateTime.now());
        boolean success = this.save(logGoodPriceDO);
        if (!success) {
            throw getAppException("保存价格变更记录失败");
        }
        return logGoodPriceDO;
    }

    /**
     * 为多个子商品添加价格变化记录
     *
     * @param map 键值对，键为子商品id，值为价格
     * @return 返回添加成功的记录
     */
    @Override
    public List<LogGoodPriceDO> addGoodPriceLogs(Map<Integer, Double> map) {
        if (ObjectValidators.isEmpty(map)) {
            throw getAppException("数据不能为空");
        }
        for (Map.Entry<Integer, Double> entry : map.entrySet()) {
            if (ObjectValidators.isEmpty(entry.getKey()) || entry.getKey() <= 0) {
                throw getAppException("子商品id不能为空或小于等于零");
            }
            if (ObjectValidators.isEmpty(entry.getValue()) || entry.getValue() <= 0.0) {
                throw getAppException("商品价格不能为空或小于等于零");
            }
        }

        List<SubGoodDO> subGoodDoList = subGoodService.list(new LambdaQueryWrapper<SubGoodDO>()
                .in(SubGoodDO::getId, new ArrayList<>(map.keySet()))
        );
        if (ObjectValidators.isEmpty(subGoodDoList) || subGoodDoList.size() < map.size()) {
            throw getAppException("部分商品不存在");
        }

        List<LogGoodPriceDO> list = new ArrayList<>(map.size());
        LogGoodPriceDO logGoodPriceDO;

        for (SubGoodDO subGoodDO : subGoodDoList) {
            logGoodPriceDO = new LogGoodPriceDO();
            logGoodPriceDO.setGoodId(subGoodDO.getGoodId());
            logGoodPriceDO.setGoodName(subGoodDO.getGoodName());
            logGoodPriceDO.setSubGoodId(subGoodDO.getId());
            logGoodPriceDO.setSubGoodName(subGoodDO.getSubGoodName());
            logGoodPriceDO.setPrice(BigDecimal.valueOf(map.get(subGoodDO.getId())));
            logGoodPriceDO.setUpdateTime(LocalDateTime.now());
            list.add(logGoodPriceDO);
        }

        boolean success = this.saveBatch(list);
        if (!success) {
            throw getAppException("保存价格更改记录失败");
        }
        return list;
    }

}
